package Core;
/*
 *  vmeRecordStore version 1.1.7
 *  Van Tan Tai (C) 2010 (3-6-2011)
 *  Plz: Remove debug info db() in release version
 */
import javax.microedition.rms.RecordStore;

public class MRecord
{
	public final byte k_ERROR_UNKNOW = -1;
	public final byte k_ERROR_OUT_OF_BOUND = 0;
	public final byte k_RECORD_STORE_EMPTY = 2;
	public final byte k_SUCCESSFUL = 3;
	public final byte k_SIZE_CONFLIC = 4;
	
	public static final byte k_P_START = 7;
	public static final byte k_P_CURRUNT = 8;
	public static final byte k_P_END = 9;
	
	public static int k_MAX_SIZE= 3*1024; // registerMaxSizeOfRecords 3 Kilobytes
	private RecordStore m_ms	= null;
	private byte arrByte[]		= null;
	private String m_REC_STORE	= null;
	private int offset			= 0;
	private int ilen			= 0;
	private byte err			= k_SUCCESSFUL;
	
	public MRecord(String rcName)
	{
		m_REC_STORE = rcName;
	}
	
	public void destroy(){
		arrByte = null;
		m_ms = null;
	}
	
	//write
	public void writeLong(long value) // 8 bytes
	{
		arrByte[offset+0] = (byte)(value & 0xFF);
		arrByte[offset+1] = (byte)((value >> 8) & 0xFF);
		arrByte[offset+2] = (byte)((value >> 16) & 0xFF);
		arrByte[offset+3] = (byte)((value >> 24) & 0xFF);
		arrByte[offset+4] = (byte)((value >> 32) & 0xFF);
		arrByte[offset+5] = (byte)((value >> 40) & 0xFF);
		arrByte[offset+6] = (byte)((value >> 48) & 0xFF);
		arrByte[offset+7] = (byte)((value >> 56) & 0xFF);
		offset += 8;
		if(offset > ilen) ilen = offset;
	}
	public void writeInt(int value) // 4 bytes
	{
		arrByte[offset+0] = (byte)(value & 0xFF);
		arrByte[offset+1] = (byte)((value >> 8) & 0xFF);
		arrByte[offset+2] = (byte)((value >> 16) & 0xFF);
		arrByte[offset+3] = (byte)((value >> 24) & 0xFF);
		offset += 4;
		if(offset > ilen) ilen = offset;
	}

	public void writeShort(short value) // 2 bytes
	{
		arrByte[offset+0] = (byte)(value & 0xFF);
		arrByte[offset+1] = (byte)((value >> 8) & 0xFF);
		offset += 2;
		if(offset > ilen) ilen = offset;
	}
	
	public void writeByte(byte value) // 1 byte
	{
		arrByte[offset+0] = (byte)(value & 0xFF);
		offset += 1;
		if(offset > ilen) ilen = offset;
	}

	public void writeBoolean(boolean value) // 1 byte
	{
		arrByte[offset+0] = (byte)(value ? 1 : 0);
		offset += 1;
		if(offset > ilen) ilen = offset;
	}
	
	public void writeString(String str)
	{
		byte[] rec = str.getBytes();
		short len = (short)str.length();
		writeShort(len);
		for(int i = 0; i < len; i++){
			arrByte[offset + i] = rec[i];
		}
		offset += len;
		if(offset > ilen) ilen = offset;
	}
	
	//read
	public long readLong() // 8 bytes
	{
		if( offset + 8 > ilen){
			err = k_ERROR_OUT_OF_BOUND;
			return -1;
		}
		long val = 0
		| ((arrByte[offset+0] & 0xFF))
		| ((arrByte[offset+1] & 0xFF) << 8)
		| ((arrByte[offset+2] & 0xFF) << 16)
		| ((((long)arrByte[offset+3]) & 0xFF) << 24)
		| ((((long)arrByte[offset+4]) & 0xFF) << 32)
		| ((((long)arrByte[offset+5]) & 0xFF) << 40)
		| ((((long)arrByte[offset+6]) & 0xFF) << 48)
		| ((((long)arrByte[offset+7]) & 0xFF) << 56);
		offset += 8;
		err = k_SUCCESSFUL;
		return val;
	}
	public int readInt() // 4 bytes
	{
		if( offset + 4 > ilen){
			err = k_ERROR_OUT_OF_BOUND;
			return -1;
		}
		int val = 0
		| (arrByte[offset+0] & 0xFF)
		| ((arrByte[offset+1] & 0xFF) << 8)
		| ((arrByte[offset+2] & 0xFF) << 16)
		| ((arrByte[offset+3] & 0xFF) << 24);
		offset += 4;
		err = k_SUCCESSFUL;
		return val;
	}

	public short readShort() // 2 bytes
	{
		if( offset + 2 > ilen){
			err = k_ERROR_OUT_OF_BOUND;
			return -1;
		}
		short val = (short)( 0
		| ((arrByte[offset+0] & 0xFF))
		| ((arrByte[offset+1] & 0xFF) << 8));
		offset += 2;
		err = k_SUCCESSFUL;
		return val;
	}
	
	public byte readByte() // 1 bytes
	{
		if( offset + 1 > ilen){
			err = k_ERROR_OUT_OF_BOUND;
			return -1;
		}
		byte val = (arrByte[offset+0]);
		offset += 1;
		err = k_SUCCESSFUL;
		return val;
	}
	
	public boolean readBoolean() // 1 bytes
	{
		if( offset + 1 > ilen){
			err = k_ERROR_OUT_OF_BOUND;
			return false;
		}
		byte val = (arrByte[offset+0]);
		offset += 1;
		err = k_SUCCESSFUL;
		return val==1;
	}	
	public String readString()
	{
		int len = readShort();
		if(len > 0){
			offset += len;
			if( offset > ilen){
				err = k_ERROR_OUT_OF_BOUND;
				return "";
			}
			err = k_SUCCESSFUL;
			return new String(arrByte, offset-len, len);
		}
		return "";
	}
	
	/** read - edit - overwrite(openTowriteNew) */
	public boolean openRecStore(boolean openTowriteNew) 
	{
		offset = 0;
		if(arrByte == null){ // init
			arrByte = new byte[k_MAX_SIZE];
			ilen = 0;
		}
		if(!openTowriteNew && ilen == 0){
			try {
				m_ms = RecordStore.openRecordStore(m_REC_STORE, true );
				
				if(m_ms.getNumRecords()==0){
					db("openRecStore > NumRecords = 0");
					err = k_RECORD_STORE_EMPTY;
					m_ms.closeRecordStore();
					return false;
				}
				db("openRecStore > Loading data... " + m_ms.getNumRecords() + " records!");
				
				this.ilen = m_ms.getRecord(1, arrByte, 0);
				
				m_ms.closeRecordStore();
			} catch (Exception e){
				db(e.toString());
				err = k_ERROR_UNKNOW;
				return false;
			}
		}
		else if(openTowriteNew){
			ilen = 0;
		}
		
		err = k_SUCCESSFUL;
		return true;
	}
	
	public void saveRecordStore(){
		try
		{
			m_ms = RecordStore.openRecordStore(m_REC_STORE, true );
			
			if(m_ms.getNumRecords() == 0)
				m_ms.addRecord(arrByte, 0, this.ilen);
			else
				m_ms.setRecord(1, arrByte, 0, this.ilen);
			
			m_ms.closeRecordStore();
		}
		catch (Exception e)
		{
			db(e.toString());
			err = k_ERROR_UNKNOW;
		}	
	}
	
	public void deleteRecStore()
	{
		arrByte = null;
		System.gc();
		ilen = 0;
		if (RecordStore.listRecordStores() != null)
		{
			try
			{
				RecordStore.deleteRecordStore(m_REC_STORE);
				err = k_SUCCESSFUL;
			}
			catch (Exception e)
			{
				db(e.toString());
				err = k_ERROR_UNKNOW;
			}
		} else err = k_RECORD_STORE_EMPTY;
	}
	
	public int seek(int position, byte from)
	{
		int p = offset;
		if(from == k_P_CURRUNT){
			p = offset + position;
		} else if (from == k_P_START){
			p = 0 + position;
		} else if (from == k_P_END){
			p = ilen - 1 + position;
		}
		if(p >= k_MAX_SIZE || p < 0){
			err = k_ERROR_OUT_OF_BOUND;
		}
		else{
			offset = p;
			err = k_SUCCESSFUL;
		}
		return offset;
	}
	
	public int lenght()
	{
		return ilen;
	}
	
	public boolean canbeReadARecord()
	{
		try
		{
			m_ms = RecordStore.openRecordStore(m_REC_STORE, true );
			
			if(m_ms.getNumRecords()==0){
				err = k_RECORD_STORE_EMPTY;
				m_ms.closeRecordStore();
				return false;
			}
			if (m_ms.getRecordSize(1) <= 0){
				err = k_RECORD_STORE_EMPTY;
				m_ms.closeRecordStore();
				return false;
			}
			
			m_ms.closeRecordStore();
		}
		catch (Exception e)
		{
			db(e.toString());
			err = k_ERROR_UNKNOW;
			return false;
		}

		err = k_SUCCESSFUL;
		return true;
	}
	
	public byte getError(){
		return err;
	}
	
	// TODO: Debug Error
	private void db(String str)
	{
		System.err.println("Msg: " + str);
	}
}
